/**
 * @file cycle_storage.c
 * @author Linquan 
 * @brief flash循环存储框架，支持自定义存储数据类型
 * @version 0.1
 * @date 2025-10-10
 * 
 * @copyright Copyright (c) 2025
 * 
 */


#include "cycle_storage.h"
#include <string.h>
#include <stdio.h>
/* 添加 存储读写擦的驱动 */


#define MCU_read(addr, buf, len)
#define MCU_write(addr, buf, len)
#define MCU_erase(addr, erase_page_num)     (STORAGE_OK)


// RTX5临界区进入：禁止任务调度和中断
static uint32_t enter_critical_section(void) 
{
    // // 保存当前中断屏蔽状态
    // uint32_t primask = __get_PRIMASK();
    
    // // 禁用所有可屏蔽中断
    // __disable_irq();
    
    // // 禁止RTX5任务调度器
    // osKernelLock();
    
    // return primask;
}

// RTX5临界区退出：恢复任务调度和中断
static void exit_critical_section(uint32_t primask) 
{
    // // 恢复RTX5任务调度器
    // osKernelUnlock();
    
    // // 恢复中断屏蔽状态
    // __set_PRIMASK(primask);
}


// 快速计算校验和的函数 - 速度优先
//static uint16_t calculate_checksum(const void *data, uint32_t length) {
//    const uint8_t *byte_data = (const uint8_t *)data;
//    uint16_t checksum = 0;
//    
//    // 快速计算校验和：简单累加 + XOR组合，速度快且实现简单
//    for (uint32_t i = 0; i < length; i++) {
//        checksum = (checksum << 1) | (checksum >> 15);  // 循环移位
//        checksum += byte_data[i];                       // 累加
//        checksum ^= byte_data[i];                       // XOR操作
//    }
//    
//    return checksum;
//}



static uint16_t checksum_xor_add(const void *data, size_t length) {
    const uint8_t *buf = (const uint8_t *)data;
    uint32_t sum = 0;
    uint32_t xor = 0;
    
    // 同时进行累加和XOR操作
    while (length >= 4) {
        uint32_t val = *(const uint32_t *)buf;
        sum += val;
        xor ^= val;
        buf += 4;
        length -= 4;
    }
    
    // 处理剩余字节
    while (length--) {
        uint8_t val = *buf++;
        sum += val;
        xor ^= val;
    }
    
    // 组合结果为16位
    return (uint16_t)(((sum >> 16) ^ (sum & 0xFFFF)) ^ xor);
}





// 检查是否是首次启动（需要初始化）
static bool is_first_boot(void) {
    uint32_t init_marker;
	MCU_read(INIT_MARKER_ADDR, (uint8_t*)&init_marker, sizeof(init_marker));
    return (init_marker != INIT_MAGIC);
}

// 设置初始化标记（表示已完成首次初始化）
static void set_initialized_flag(void) 
{
	uint32_t init_marker = INIT_MAGIC;
	MCU_write(INIT_MARKER_ADDR, (uint8_t*)&init_marker, sizeof(init_marker));
    
}




// 查找最新的有效存储单元
static int32_t find_latest_valid_unit(void) {
    FlashStorageUnitTypeDef unit;
    int32_t latest_index = -1;
    uint32_t max_counter = 0;
    
    // 遍历所有可能的存储单元
    for (uint32_t i = 0; i < MAX_STORAGE_UNITS; i++) {
        const uint32_t addr = CYCLE_FLASH_SECTOR_ADDR + i * STORAGE_UNIT_SIZE;
        
        // 读取存储单元内容
       // memcpy(&unit, (const void*)addr, STORAGE_UNIT_SIZE);
       MCU_read(addr, (uint8_t*)&unit, STORAGE_UNIT_SIZE);
		
		
        // 检查魔术字
        if (unit.magic != STORAGE_MAGIC) {
            continue;
        }
        
        // 验证校验和
        const uint16_t computed_checksum = checksum_xor_add(
            &unit.params, sizeof(DeviceParamsTypeDef)
        );
        
        if (unit.checksum == computed_checksum) {
            // 找到有效单元，检查是否是最新的
            if (unit.counter > max_counter) {
                max_counter = unit.counter;
                latest_index = i;
            }
        }
    }
    
    return latest_index;
}

// 查找下一个可写入的存储单元
static int32_t find_next_write_unit(void) {
    FlashStorageUnitTypeDef unit;
    
    // 寻找第一个空单元（魔术字不正确）
    for (uint32_t i = 0; i < MAX_STORAGE_UNITS; i++) {
        const uintptr_t  addr = CYCLE_FLASH_SECTOR_ADDR + i * STORAGE_UNIT_SIZE;
        memcpy(&unit, (const void*)addr, sizeof(unit.magic));  // 只需要读取魔术字即可
        
        if (unit.magic != STORAGE_MAGIC) {
            return i;  // 找到空单元
        }
    }
    
    // 没有空单元，需要擦除扇区
    return -1;
}


// 擦除扇区函数 - 需要根据具体MCU实现
uint8_t FlashStorage_EraseSector(void) 
{
	/* 擦除sector */
   const bool success = MCU_erase(CYCLE_FLASH_SECTOR_ADDR, 1);
    
	 // 设置初始化标记
     set_initialized_flag();
	
    return success ? STORAGE_OK : STORAGE_ERROR;
}




/*
	初始化存储系统
*/ 
uint8_t FlashStorage_Init(void) 
{
	if (is_first_boot()) 
	{
		printf("flash cycle storage erase\r\n");
        // 擦除整个扇区，清除原有数据
        if (FlashStorage_EraseSector() != STORAGE_OK) 
		{
            return STORAGE_ERROR;
        }   
    }
	
    return STORAGE_OK;
}

/*
	写入参数到Flash
*/ 
uint8_t FlashStorage_WriteParams(const DeviceParamsTypeDef *params) {
    if (params == NULL) {
        return STORAGE_ERROR;
    }
    
    // 查找最新的有效单元，确定下一个计数器值
    const int32_t latest_index = find_latest_valid_unit();
    uint32_t next_counter = 1;
    
    if (latest_index != -1) {
        FlashStorageUnitTypeDef latest_unit;
        const uintptr_t addr = CYCLE_FLASH_SECTOR_ADDR + latest_index * STORAGE_UNIT_SIZE;
        memcpy(&latest_unit, (const void*)addr, sizeof(latest_unit.counter) + sizeof(latest_unit.magic));
        next_counter = latest_unit.counter + 1;
    }
    
    // 查找下一个可写入的单元
    int32_t write_index = find_next_write_unit();
    if (write_index == -1) {
        // 没有可用单元，擦除扇区
        if (FlashStorage_EraseSector() != STORAGE_OK) {
            return STORAGE_ERROR;
        }
        write_index = 0;  // 擦除后第一个单元可用
    }
    
    // 准备写入数据
    FlashStorageUnitTypeDef write_unit;
    write_unit.magic = STORAGE_MAGIC;
    write_unit.counter = next_counter;
    memcpy(&write_unit.params, params, sizeof(DeviceParamsTypeDef));
    write_unit.checksum = checksum_xor_add(&write_unit.params, sizeof(DeviceParamsTypeDef));
     
	uint32_t write_addr = CYCLE_FLASH_SECTOR_ADDR + write_index * STORAGE_UNIT_SIZE;
	
   /* flash 写入 */
	uint32_t irq_state = enter_critical_section();
	MCU_write(write_addr, (uint8_t*)&write_unit, STORAGE_UNIT_SIZE);
    exit_critical_section(irq_state);
	
    return STORAGE_OK;
}

/*
	读取最新的参数
*/ 
uint8_t FlashStorage_ReadLatestParams(DeviceParamsTypeDef *params)
{
    if (params == NULL) 
	{
        return STORAGE_ERROR;
    }
    
    const int32_t latest_index = find_latest_valid_unit();
	
    if (latest_index == -1) 
	{
        return STORAGE_NO_VALID_DATA;  // 没有找到有效数据
    }
    
    // 读取最新的参数
    const uint32_t addr = CYCLE_FLASH_SECTOR_ADDR + latest_index * STORAGE_UNIT_SIZE;
    FlashStorageUnitTypeDef latest_unit;
    
	
	/* flash 读取 */
	MCU_read(addr, (uint8_t*)&latest_unit, STORAGE_UNIT_SIZE);
	
    memcpy(params, &latest_unit.params, sizeof(DeviceParamsTypeDef));
    return STORAGE_OK;
}

/*
	获取有效参数数量
*/ 
uint8_t FlashStorage_GetParamsCount(void) 
{
    FlashStorageUnitTypeDef unit;
    uint8_t count = 0;
    
    for (uint32_t i = 0; i < MAX_STORAGE_UNITS; i++) 
	{
        const uintptr_t addr = CYCLE_FLASH_SECTOR_ADDR + i * STORAGE_UNIT_SIZE;
        memcpy(&unit, (const void*)addr, STORAGE_UNIT_SIZE);
        
        if (unit.magic == STORAGE_MAGIC) 
		{
            const uint16_t computed_checksum = checksum_xor_add(
													&unit.params, sizeof(DeviceParamsTypeDef));
            
            if (unit.checksum == computed_checksum) 
			{
                count++;
            }
        }
    }
    
    return count;
}
    